package com.the_last.listener;

import com.rabbitmq.client.Channel;
import com.the_last.config.RabbitConfig;
import com.the_last.service.OrderTimeoutService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 订单超时消息监听器
 * 
 * @author zhanghaifeng
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OrderTimeoutListener {
    
    private final OrderTimeoutService orderTimeoutService;
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 监听订单超时处理队列的消息
     * 处理从延时队列转移过来的超时订单消息
     */
    @RabbitListener(queues = RabbitConfig.ORDER_TIMEOUT_QUEUE)
    public void handleOrderTimeoutMessage(String orderIdStr, Channel channel, Message amqpMessage) throws IOException {
        String currentTime = LocalDateTime.now().format(FORMATTER);
        long deliveryTag = amqpMessage.getMessageProperties().getDeliveryTag();
        String messageId = amqpMessage.getMessageProperties().getMessageId();
        
        // 如果消息没有ID，生成一个唯一ID
        if (messageId == null || messageId.isEmpty()) {
            messageId = UUID.randomUUID().toString();
        }
        
        log.info("=== 订单超时处理队列监听器 ===");
        log.info("[{}] 收到订单超时消息", currentTime);
        log.info("订单ID: {}", orderIdStr);
        log.info("消息ID: {}", messageId);
        log.info("DeliveryTag: {}", deliveryTag);
        
        try {
            // 解析订单ID
            Long orderId = Long.parseLong(orderIdStr.trim());
            log.info("开始处理订单超时，订单ID: {}", orderId);
            
            // 调用业务服务处理订单超时
            boolean success = orderTimeoutService.processOrderTimeout(orderId, messageId);
            
            if (success) {
                log.info("订单超时处理成功，订单ID: {}", orderId);
                // 手动确认消息
                channel.basicAck(deliveryTag, false);
                log.info("消息确认成功，DeliveryTag: {}", deliveryTag);
            } else {
                log.warn("订单超时处理失败，订单ID: {}", orderId);
                // 处理失败，拒绝消息但不重新入队（避免无限循环）
                channel.basicNack(deliveryTag, false, false);
                log.info("消息拒绝成功（不重新入队），DeliveryTag: {}", deliveryTag);
            }
            
        } catch (NumberFormatException e) {
            log.error("订单ID格式错误: {}", orderIdStr, e);
            // 格式错误的消息直接丢弃，不重新入队
            channel.basicNack(deliveryTag, false, false);
            
        } catch (Exception e) {
            log.error("处理订单超时消息异常，订单ID: {}, 消息ID: {}", orderIdStr, messageId, e);
            // 发生异常时拒绝消息并重新入队，但限制重试次数
            Integer retryCount = (Integer) amqpMessage.getMessageProperties().getHeaders().get("x-retry-count");
            if (retryCount == null) {
                retryCount = 0;
            }
            
            if (retryCount < 3) {
                // 增加重试次数
                amqpMessage.getMessageProperties().getHeaders().put("x-retry-count", retryCount + 1);
                log.info("消息处理失败，重新入队，重试次数: {}", retryCount + 1);
                channel.basicNack(deliveryTag, false, true);
            } else {
                // 重试次数过多，丢弃消息
                log.error("消息处理失败次数过多，丢弃消息，订单ID: {}", orderIdStr);
                channel.basicNack(deliveryTag, false, false);
            }
        } finally {
            log.info("=========================");
        }
    }
}